package com.ccp.dev.workflow.service;

import com.ccp.dev.core.basic.base.BaseService;
import com.ccp.dev.core.basic.util.ContextUtil;
import com.ccp.dev.core.basic.util.UUIDUtils;
import com.ccp.dev.core.basic.web.query.QueryFilter;
import com.ccp.dev.core.util.BeanUtils;
import com.ccp.dev.core.util.StringPool;
import com.ccp.dev.system.consts.SecretUtil;
import com.ccp.dev.system.model.SysUser;
import com.ccp.dev.workflow.bpmconst.BpmConst;
import com.ccp.dev.workflow.dao.ProcessCopyToDao;
import com.ccp.dev.workflow.model.ActDefModel;
import com.ccp.dev.workflow.model.ProcessCopyTo;
import com.ccp.dev.workflow.model.ProcessRun;
import com.ccp.dev.workflow.model.SysTemplate;
import com.ccp.dev.workflow.model.bpm.CcMessageType;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * ClassDescribe    流程抄送转发 Service逻辑层
 * @author: fanruiqi
 * Date: 2019-09-26
 * Since:1
 * To change this template use File | Settings | File Templates.
 */
@Service
public class ProcessCopyToService extends BaseService<ProcessCopyTo> {

    @Resource
    private ProcessCopyToDao processCopyToDao;
    @Resource
    private BpmNodeUserService bpmNodeUserService;
    @Resource
    private TaskMessageService taskMessageService;
    @Resource
    private SysTemplateService sysTemplateService;
    @Resource
    private ProcessRunService processRunService;

    /**
     * 获取我的抄送列表
     * @param queryFilter
     * @return
     */
    public List<ProcessCopyTo> queryMyList(QueryFilter queryFilter) {
        return processCopyToDao.queryMyList(queryFilter);
    }

    /**
     * 根据运行Id获取用户数据。
     * @param runId
     * @return
     */
    public List<ProcessCopyTo> queryUserInfoByRunId(String runId) {
        return processCopyToDao.queryUserInfoByRunId(runId);
    }

    /**
     * 标记任务抄送消息为已读
     * @param copyIds
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateReadStatus(String copyIds) {
        String[] idArr = copyIds.split(",");
        for(String id : idArr){
            if(StringUtils.isNotEmpty(id)){
                ProcessCopyTo copyTo = processCopyToDao.getById(id);
                copyTo.setIsRead(ProcessCopyTo.READ);
                copyTo.setReadTime(new Date());
                processCopyToDao.update(copyTo);
            }
        }
    }

    /**
     * 处理抄送任务
     * @param processRun 流程执行封装对象
     * @param variables 流程变量
     * @param preTaskUserId 上一个任务执行人
     * @param actDefModel 流程模型
     */
    public void handlerCopyTask(ProcessRun processRun, Map<String, Object> variables, String preTaskUserId, ActDefModel actDefModel) throws Exception {
        if (BeanUtils.isEmpty(actDefModel)) {
            return;
        }
        if (BeanUtils.isEmpty(processRun)) {
            return;
        }

        String procDefId = processRun.getProcDefId();
        String typeId = actDefModel.getTypeId();
        Integer allowFinishedCc = actDefModel.getAllowFinishedCc();
        // 流程未设置允许半截抄送时，不处理抄送
        if (allowFinishedCc.intValue() != 1) {
            return;
        }
        String subject = processRun.getSubject();
        String startUserId = processRun.getCreatorId();
        String procInstId = processRun.getProcInstId();
        List<SysUser> copyConditionUsers = bpmNodeUserService.queryCopyUserByProcDefId(procDefId, procInstId, startUserId, variables, preTaskUserId);
        //根据密级过滤后的抄送人
        List<SysUser> newUserList = new ArrayList<>(20);
        if (BeanUtils.isEmpty(copyConditionUsers)) {
            return;
        }else{
            //将抄送人根据密级进行过滤
            int dataPrivacyLevel = processRunService.getPrivacyLevelByProcessRun(processRun);
            for(SysUser sysUser:copyConditionUsers){
                if(SecretUtil.getUserDataSecretMap().get(sysUser.getPrivacyLevel())>=dataPrivacyLevel){
                    newUserList.add(sysUser);
                }
            }
        }
        if (BeanUtils.isEmpty(newUserList)) {
            return;
        }
        addCopyTo(newUserList, processRun, typeId);
        handlerCopyMessage(procDefId, newUserList, variables, subject, processRun.getRunId(), actDefModel.getCcMessageType());
    }

    private void handlerCopyMessage(String procDefId, List<SysUser> copyConditionUsers, Map<String, Object> variables, String subject, String runId, String ccMessageType) throws Exception {
        if (BeanUtils.isEmpty(copyConditionUsers)) {
            return;
        }

        SysUser currentUser = (SysUser) ContextUtil.getCurrentUser();
        String informTypes = "";
        if (com.alibaba.druid.util.StringUtils.isEmpty(ccMessageType)) {
            // 若抄送类型未设置，则默认为站内消息
            ccMessageType = "{\"inner\":1,\"mail\":0,\"sms\":0}";
        }
        JSONObject jsonObject = JSONObject.fromObject(ccMessageType);
        CcMessageType cc = (CcMessageType) JSONObject.toBean(jsonObject, CcMessageType.class);

        Map<String, String> msgTempMap = sysTemplateService.getTempByFun(SysTemplate.USE_TYPE_COPYTO);

        //邮件
        if(cc.getMail()==1){
            if (!informTypes.contains(BpmConst.MESSAGE_TYPE_MAIL)) {
                informTypes =  BpmConst.MESSAGE_TYPE_MAIL+ "," +informTypes ;
            }
        }

        //站内消息
        if(cc.getInner()==1){
            if (!informTypes.contains(BpmConst.MESSAGE_TYPE_INNER)) {
                informTypes =  BpmConst.MESSAGE_TYPE_INNER+ "," + informTypes;
            }
        }

        //短息
        if(cc.getSms()==1){
            if (!informTypes.contains(BpmConst.MESSAGE_TYPE_SMS)) {
                informTypes =  BpmConst.MESSAGE_TYPE_SMS+ "," + informTypes;
            }
        }
        //截取逗号
        if(informTypes.substring(informTypes.length()-1).equals(StringPool.COMMA)){
            informTypes=informTypes.substring(0,informTypes.length()-1);
        }
        taskMessageService.sendMessage(currentUser, copyConditionUsers, informTypes, msgTempMap, subject, "", null, runId, null);
    }

    /**
     * 保存抄送对象
     * @param copyConditionUsers 抄送条件用户
     * @param processRun 流程运行封装对象
     * @param typeId 流程分类
     */
    private void addCopyTo(List<SysUser> copyConditionUsers, ProcessRun processRun, String typeId) {
        String procInstId = processRun.getProcInstId();
        String startUserId = processRun.getCreatorId();
        // 姓名
        String creator = processRun.getCreator();

        for (SysUser sysUser : copyConditionUsers) {
            String copyUserId = sysUser.getUserId();
            String copyUserName = sysUser.getFullName();
            ProcessCopyTo copyTo = new ProcessCopyTo();
            copyTo.setProcInstId(procInstId);
            copyTo.setCcTime(new Date());
            copyTo.setCcUId(copyUserId);
            copyTo.setCcUName(copyUserName);
            copyTo.setCpType(ProcessCopyTo.CPTYPE_COPY);
            copyTo.setIsRead(ProcessCopyTo.NOT_READ);
            copyTo.setRunId(processRun.getRunId());
            copyTo.setSubject(processRun.getSubject());
            copyTo.setDefTypeId(typeId);
            copyTo.setCreateId(startUserId);
            copyTo.setCreator(creator);
            copyTo.setCopyId(UUIDUtils.getUUIDFor32());
            //抄送时间，即抄送流程创建时间
            copyTo.setCcTime(new Date());
            processCopyToDao.add(copyTo);
        }
    }

    /**
     * 根据流程runId删除抄送转发事宜
     * @param runId
     */
    public void delByRunId(String runId) {
        processCopyToDao.delByRunId(runId);
    }
}
